﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ToDoBasket.Model;

namespace ToDoBasket.Custom
{
    public class EnterPressedRoutedEventArgs : RoutedEventArgs
    {
        public EnterPressedRoutedEventArgs(RoutedEvent routedEvent, object source)
            : base(routedEvent, source)
        {
            Lowest = false;
        }
        public Potato NewPotato { get; set; }
        public bool Lowest { get; set; }
    }

    [TemplatePart(Name = "tbPrefix", Type = typeof(TextBlock))]
    [TemplatePart(Name = "tbPotato", Type = typeof(TextBox))]
    [TemplatePart(Name = "tbTips", Type = typeof(TextBlock))]
    [TemplatePart(Name = "tbEnter", Type = typeof(TextBlock))]
    [TemplatePart(Name = "btnClear", Type = typeof(Button))]
    public class PotatoTextBox : Control, INotifyPropertyChanged
    {
        //注册事件
        public static readonly RoutedEvent TextChangedEvent = EventManager.RegisterRoutedEvent("TextChanged",
            RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(PotatoTextBox));
        public static readonly RoutedEvent EnterPressedEvent = EventManager.RegisterRoutedEvent("EnterPressed",
            RoutingStrategy.Bubble, typeof(EventHandler<EnterPressedRoutedEventArgs>), typeof(PotatoTextBox));
        public static readonly RoutedEvent BtnClearClickEvent = EventManager.RegisterRoutedEvent("BtnClearClick",
            RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(PotatoTextBox));
        //事件处理器属性
        public event RoutedEventHandler TextChanged
        {
            add { AddHandler(TextChangedEvent, value); }
            remove { RemoveHandler(TextChangedEvent, value); }
        }
        public event EventHandler<EnterPressedRoutedEventArgs> EnterPressed
        {
            add { AddHandler(EnterPressedEvent, value); }
            remove { RemoveHandler(EnterPressedEvent, value); }
        }
        public event RoutedEventHandler BtnClearClick
        {
            add { AddHandler(BtnClearClickEvent, value); }
            remove { RemoveHandler(BtnClearClickEvent, value); }
        }
        static PotatoTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PotatoTextBox), new FrameworkPropertyMetadata(typeof(PotatoTextBox)));
        }

        private string prefix;

        public string Prefix
        {
            get { return prefix; }
            set
            {
                prefix = value;
                this.RaisePropertyChanged("Prefix");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private string[] tips =
        {
            "\"土豆,土豆\"就是\"ToDo\"",
            "使用\"#标签\"可以添加标签，帮助管理你的土豆筐",
            "使用\"!!\"可以标记为二级重要程度",
            "开头输入\"$\"可以将土豆移到列表底部"
        };

        private TextBlock tbPrefix;
        private TextBox tbPotato;
        private TextBlock tbTips;
        private TextBlock tbEnter;
        private Button btnClear;

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Prefix = "";
            DataContext = this;

            tbPrefix = Template.FindName("tbPrefix", this) as TextBlock;
            tbPotato = Template.FindName("tbPotato", this) as TextBox;
            tbTips = Template.FindName("tbTips", this) as TextBlock;
            tbEnter = Template.FindName("tbEnter", this) as TextBlock;
            btnClear = Template.FindName("btnClear", this) as Button;

            if (tbPrefix != null)
                tbPrefix.MouseLeftButtonDown += (s, e) => ClearPrefix();

            if (tbPotato != null)
            {
                tbPotato.PreviewKeyDown += (s, e) =>
                {
                    if (e.Key == Key.Enter)
                        InputFinished();
                    else if (e.Key == Key.Back && tbPotato.Text.Length == 0)
                        ClearPrefix();
                };
                tbPotato.GotFocus += (s, e) =>
                {
                    if (tbTips.Visibility == Visibility.Visible)
                        tbTips.Text = tips[new Random().Next(tips.Length)];
                };
                tbPotato.LostFocus += (s, e) => tbTips.Text = "添加新土豆";
                tbPotato.TextChanged += (s, e) => RaiseEvent(new RoutedEventArgs(TextChangedEvent, this));
            }

            if (tbEnter != null)
                tbEnter.MouseLeftButtonDown += (s, e) => InputFinished();

            if (btnClear != null)
                btnClear.Click += (s, e) => ClearPrefix();
        }

        //完成输入
        void InputFinished()
        {
            string original = tbPotato.Text.Trim();

            if (!Potato.IsValid(original)) return;
            EnterPressedRoutedEventArgs args = new EnterPressedRoutedEventArgs(EnterPressedEvent, this);
            string prefixStr = Prefix;
            if (!string.IsNullOrEmpty(Prefix)) prefixStr += " ";
            if (original[0].Equals('$'))
            {
                args.NewPotato = new Potato(prefixStr + original.Remove(0, 1));
                args.Lowest = true;
            }
            else
            {
                args.NewPotato = new Potato(prefixStr + original);
            }

            //触发事件
            RaiseEvent(args);

            //if (Prefix == null || Prefix.Equals(""))
            tbPotato.Clear();
            tbTips.Text = tips[new Random().Next(tips.Length)];
        }

        void ClearPrefix()
        {
            Prefix = "";
            RaiseEvent(new RoutedEventArgs(BtnClearClickEvent, this));
        }
    }
}
